package system

import (
	"bottle/global"
	"bottle/model/common/response"
	"bottle/model/system"
	systemReq "bottle/model/system/request"
	systemRes "bottle/model/system/response"
	"bottle/utils"
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"time"
)

type PaperApi struct{}

func (p *PaperApi) SendPaper(c *gin.Context) {
	var req systemReq.SendPaperRequest
	err := c.ShouldBind(&req)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	err = utils.Verify(req, utils.SendPaperVerify)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	//限制每天扔瓶子数量
	cacheKey := fmt.Sprintf("sendPaper@%d", req.UserId)
	throwNum, err := global.GVA_REDIS.Get(context.Background(), cacheKey).Int()
	if throwNum >= 5 {
		response.FailWithMessage("今天不能再扔瓶子了", c)
		return
	}

	var paper = system.Paper{UserID: req.UserId, Content: req.Content, CreateTime: time.Now().Unix()}
	err = global.GVA_DB.Create(&paper).Error
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	global.GVA_REDIS.Incr(context.Background(), cacheKey)

	//设置过期时间为明晚0点
	now := time.Now()
	nextDay := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, time.Local)
	duration := nextDay.Sub(now)
	global.GVA_REDIS.Expire(context.Background(), cacheKey, duration)
	response.Ok(c)

}

func (p *PaperApi) PickUpBottle(c *gin.Context) {
	var req systemReq.IDReq
	err := c.ShouldBind(&req)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	err = utils.Verify(req, utils.IDVerify)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	//限制每天捡瓶子的数量
	cacheKey := fmt.Sprintf("pickUpBottle@%d", req.ID)
	pickUpNum, err := global.GVA_REDIS.Get(context.Background(), cacheKey).Int()
	if pickUpNum >= 5 {
		response.FailWithMessage("明天再来捡吧", c)
		return
	}

	//自己已经丢弃的瓶子不能再被自己捞到
	//自己已经回复的瓶子不能再被捞到
	var papers []struct{ PaperID int64 }
	global.GVA_DB.Model(&system.ReplyPaper{}).Where("accept_id = ?", req.ID).Find(&papers)
	var ids []int64
	for _, v := range papers {
		ids = append(ids, v.PaperID)
	}

	var paper system.Paper
	query := global.GVA_DB.Where("del=?", -1).Where("user_id<>?", req.ID).Order("id DESC")
	if len(ids) > 0 {
		query.Where("id NOT IN ?", ids)
	}
	err = query.First(&paper).Error
	//err = global.GVA_DB.Where("del=?", -1).Where("user_id<>?", req.ID).Where("id NOT IN ?", ids).First(&paper).Error
	//今天捡瓶子数量+1
	global.GVA_REDIS.Incr(context.Background(), cacheKey)
	//设置过期时间为明晚0点
	now := time.Now()
	nextDay := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, time.Local)
	duration := nextDay.Sub(now)
	global.GVA_REDIS.Expire(context.Background(), cacheKey, duration)
	if err != nil {
		response.FailWithMessage("没有捞到瓶子", c)
		return
	}
	var user system.User
	global.GVA_DB.Where("id=?", paper.UserID).First(&user)
	result := systemRes.PickUpBottleResponse{
		PaperId:  paper.ID,
		Content:  paper.Content,
		UserId:   user.ID,
		Username: user.Username,
		Avatar:   user.Avatar,
		Gender:   user.Gender,
		UUID:     user.UUID,
	}
	response.OkWithData(result, c)
	return
}

func (p *PaperApi) ReplyPaper(c *gin.Context) {
	var req systemReq.ReplyPaperRequest
	err := c.ShouldBind(&req)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	err = utils.Verify(req, utils.ReplyPaperVerify)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	replyPaper := system.ReplyPaper{PaperID: req.PaperId, UserID: req.SenderId, AcceptID: req.ID, CreateTime: time.Now().Unix(), IsReply: req.IsReply}
	global.GVA_DB.Create(&replyPaper)
	response.Ok(c)
	return
}

func (p *PaperApi) GetPaperContent(c *gin.Context) {
	var req systemReq.GetPaperContentRequest
	err := c.ShouldBind(&req)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	err = utils.Verify(req, utils.GetPaperContentVerify)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	var sender system.User
	err = global.GVA_DB.Where("uuid = ?", req.SenderUUID).First(&sender).Error
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	var replyPaper system.ReplyPaper
	err = global.GVA_DB.Where("user_id = ?", sender.ID).Where("accept_id = ?", req.AcceptId).Preload("Paper").Order("id DESC").First(&replyPaper).Error
	if err != nil {
		response.Fail(c)
		return
	}
	response.OkWithData(replyPaper.Paper.Content, c)
	return
}

//获取可捡和扔瓶子的数量
func (p *PaperApi) GetPickAndThrowNum(c *gin.Context) {
	var req systemReq.IDReq
	err := c.ShouldBind(&req)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	err = utils.Verify(req, utils.GetPaperContentVerify)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	throwKey := fmt.Sprintf("sendPaper@%d", req.ID)
	throwNum, err := global.GVA_REDIS.Get(context.Background(), throwKey).Int()
	pickKey := fmt.Sprintf("pickUpBottle@%d", req.ID)
	pickNum, err := global.GVA_REDIS.Get(context.Background(), pickKey).Int()
	var res systemRes.GetPickAndThrowNumResponse
	res.PickNum = 5 - pickNum
	res.ThrowNum = 5 - throwNum
	response.OkWithData(res, c)
	return
}